﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using CLEX.ServiceContracts;
using CLEX.DataContracts;
using CLEX.Server.DAL;
using CLEX.Server.Host.Helpers;

namespace CLEX.Server.Host
{
    public class AdminService : ServiceBase, IAdminService
    {
        public List<DatabaseData> GetAllDatabases()
        {
            return DatabaseDAL.GetAll();
        }

        public DatabaseData GetDatabase(int databaseId)
        {
            return DatabaseDAL.Get(databaseId);
        }

        public DatabaseData CreateDatabase(DatabaseData database)
        {
            return DatabaseDAL.Create(database);
        }

        public void UpdateDatabase(DatabaseData database)
        {
            DatabaseDAL.Update(database);
        }

        public void DeleteDatabase(DatabaseData database)
        {
            DatabaseDAL.Delete(database);
        }



        public List<FriendRequestData> GetAllFriendRequests()
        {
            return FriendRequestDAL.GetAll();
        }

        public FriendRequestData GetFriendRequest(int fromUserId, int toUserId)
        {
            return FriendRequestDAL.Get(fromUserId, toUserId);
        }

        public FriendRequestData CreateFriendRequest(FriendRequestData friendRequest)
        {
            return FriendRequestDAL.Create(friendRequest);
        }

        public void UpdateFriendRequest(FriendRequestData friendRequest)
        {
            FriendRequestDAL.Update(friendRequest);
        }

        public void DeleteFriendRequest(FriendRequestData friendRequest)
        {
            FriendRequestDAL.Delete(friendRequest);
        }



        public List<FriendshipData> GetAllFriendships()
        {
            return FriendshipDAL.GetAll();
        }

        public FriendshipData GetFriendship(int user1Id, int user2Id)
        {
            return FriendshipDAL.Get(user1Id, user2Id);
        }

        public FriendshipData CreateFriendship(FriendshipData friendship)
        {
            return FriendshipDAL.Create(friendship);
        }

        public void UpdateFriendship(FriendshipData friendship)
        {
            FriendshipDAL.Update(friendship);
        }

        public void DeleteFriendship(FriendshipData friendship)
        {
            FriendshipDAL.Delete(friendship);
        }



        public List<SharedDatabaseData> GetAllSharedDatabases()
        {
            return SharedDatabaseDAL.GetAll();
        }

        public SharedDatabaseData GetSharedDatabase(int databaseId, int sharedUserId)
        {
            return SharedDatabaseDAL.Get(databaseId, sharedUserId);
        }

        public SharedDatabaseData CreateSharedDatabase(SharedDatabaseData sharedDatabase)
        {
            return SharedDatabaseDAL.Create(sharedDatabase);
        }

        public void UpdateSharedDatabase(SharedDatabaseData sharedDatabase)
        {
            SharedDatabaseDAL.Update(sharedDatabase);
        }

        public void DeleteSharedDatabase(SharedDatabaseData sharedDatabase)
        {
            SharedDatabaseDAL.Delete(sharedDatabase);
        }



        public List<UserData> GetAllUsers()
        {
            return UserDAL.GetAll().Select(p => new UserData(p)).ToList();
        }

        public UserData GetUser(int userId)
        {
            return new UserData(UserDAL.Get(userId));
        }

        public UserData CreateUser(UserData user)
        {
            string password = "password";
            string salt = PasswordHelper.GenerateSalt(200);
            UserFullData full = new UserFullData(user, password, salt);
            return new UserData(UserDAL.Create(full));
        }

        public void UpdateUser(UserData user)
        {
            UserFullData full = UserDAL.Get(user.UserId);
            full.Username = user.Username;
            full.IsAdmin = user.IsAdmin;
            full.Email = user.Email;
            UserDAL.Update(full);
        }

        public void DeleteUser(UserData user)
        {
            UserFullData full = UserDAL.Get(user.UserId);
            UserDAL.Delete(full);
        }

        public PasswordChangeResultData ChangeUserPassword(int userId, string oldPassword, string newPassword)
        {
            if (newPassword.Length > 20)
            {
                return PasswordChangeResultData.NewPasswordTooLong;
            }
            if (newPassword.Length < 5)
            {
                return PasswordChangeResultData.NewPasswordTooShort;
            }
            if (newPassword.All(p => !char.IsDigit(p)))
            {
                return PasswordChangeResultData.MissingADigit;
            }
            if (newPassword.All(p => !char.IsLetter(p)))
            {
                return PasswordChangeResultData.MissingALetter;
            }

            UserFullData user = UserDAL.Get(userId);
            if (!PasswordHelper.IsPassword(user.HashedPassword, user.PasswordSalt, oldPassword))
            {
                return PasswordChangeResultData.InvalidOldPassword;
            }

            string newSalt = PasswordHelper.GenerateSalt(200);
            string newHashedPassword = PasswordHelper.Hash(newPassword, newSalt);
            user.PasswordSalt = newSalt;
            user.HashedPassword = newHashedPassword;
            UserDAL.Update(user);
            return PasswordChangeResultData.ChangedSuccessfully;
        }
    }
}
